/*******************************************************************************************
 *      @name   A.c
 *      @brief  这是在linux系统下使用fork函数创建子进程并加载新的代码段和数据段的代码案例
 *      @date   2025/02/08
 *      @author cecelmx@126.com 
 *      @note
 *          1.在进程中调用fork函数的时候就已经创建了子进程，所以子进程会拷贝父进程的代码段和数据段！
 *          2.当子进程创建完成后，父进程和子进程是各自具有独立的进程空间，各不影响
 *          3.可以使用system函数实现加载新的代码段和数据段到创建的子进程中
 *          4.linux系统下所有的shell命令的本质都是可执行文件
 *      @version  xx.xx.xx   主版本号.次版本号.修正版本号
 * 
 *      CopyRight (c)   2024-2025   Your Name     All Right Reserved
 * 
 * ****************************************************************************************/
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <stdlib.h>

#define FILE_PATH   "./log.txt"

int main()
{
    int status = 0;       //局部变量，属于数据段
    pid_t child_pid = 0;  //局部变量，属于数据段，用于记录子进程的PID

    //调用了fork创建子进程，此时已经创建新的子进程 
    child_pid = fork();

    //需要区分父进程和子进程，因为父进程和子进程具有各自独立的进程空间
    if(child_pid > 0)
    {
        //父进程
        wait(NULL); //具有阻塞性质的，如果子进程没结束，则wait函数会阻塞
        
        //打开文件
        FILE *fp = fopen(FILE_PATH,"rb");
        if(fp == NULL)
        {
            fprintf(stderr,"fopen [%s] error,errno = %d,%s\n",
                                        FILE_PATH,errno,strerror(errno));
            exit(-1);
        }

        char timebuf[128] ={0};

        for(;;)
        {
            if(feof(fp) != 0)
            break;

            fgets(timebuf,sizeof(timebuf),fp);
            printf("%s",timebuf);

        }

        fclose(fp);
    }
    else if(child_pid == 0)
    {
        //子进程
        printf("I am child,my process pid = %d,my parent pid = %d\n",getpid(),getppid());

        //新动作
        system("./B"); //执行可执行文件B
    }
    else
    {
        //异常时
        fprintf(stderr,"fork error,errno = %d,%s\n",errno,strerror(errno));
        return -1;
    }

   
    return 0;
}